import csv
import pathlib

RADIUSSCALE = 100
DEFAULTMASS = 0.0
DEFAULTRADIUS = 1.5

class Element:
    def __init__(self) -> None:
        self.number: int = 0
        self.symbol: str = "Unknown"
        self.name: str = "Unknown"
        self.mass: float = DEFAULTMASS
        self.CPK_color: str = "#CCCCCC"
        self.vdw_radius: float = DEFAULTRADIUS

    def setValue(self, number: int, symbol: str, name: str, mass: float,
                 CPK_color: str, vdw_radius: float) -> None:
        self.number = number
        self.symbol = symbol
        self.name = name
        self.mass = mass
        self.CPK_color = CPK_color
        self.vdw_radius = vdw_radius

def generateAllElements() -> list[Element]:
    elements: list[Element] = []
    elements.append(Element())
    with open(str(pathlib.Path(__file__).parent) + "\elements.csv", 'r', 
              encoding="utf8") as file:
        data = csv.reader(file)
        head = next(data)
        for row in data:
            element = Element()
            if row[3] == "":
                mass = DEFAULTMASS
            else:
                mass = float(row[3])
            if row[9] == "":
                radius = DEFAULTRADIUS
            else:
                radius = float(row[9]) / RADIUSSCALE
            element.setValue(int(row[0]), row[1], row[2],mass, row[4], radius)
            elements.append(element)
    return elements

ALLELEMENTS = generateAllElements()

def findElementNumberBySymbol(symbol:str) -> int:
    for element in ALLELEMENTS:
        if symbol == element.symbol:
            return element.number

class Atom:
    def __init__(self, symbol:str, x:float, y:float, z:float, number:int) -> None:
        self.symbol = symbol
        self.x = x
        self.y = y
        self.z = z
        self.number = number

class Molecule:
    def __init__(self) -> None:
        self.number_atoms:int = 0
        self.comment:str = ""
        self.atoms:list[Atom] = []

class XYZReader:
    def Open(filename:str) -> Molecule:
        with open(filename, "r") as file:
            number_atoms = int(file.readline().strip())
            if number_atoms > 0:
                mol = Molecule()
                mol.number_atoms = number_atoms
                mol.comment = file.readline().strip()
                for i in range(number_atoms):
                    data = file.readline().split()
                    symbol = data[0]
                    number = findElementNumberBySymbol(symbol)
                    atom = Atom(symbol, float(data[1]), float(data[2]), 
                                float(data[3]), number)
                    mol.atoms.append(atom)
        return mol
